package com.xbongbong.paas.controller.workflow;

import com.alibaba.fastjson.JSON;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowAddSignatureDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowBackDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowCommitAgainDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowCommitDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowRefuseDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowRevokeDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowSignatureItemDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowStorageDTO;
import com.xbongbong.paas.pojo.workflow.operate.dto.WorkflowTransferDTO;
import com.xbongbong.paas.pojo.workflow.operate.vo.WorkflowAddSignatureVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.service.workflow.WorkflowApprovalOperatorService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * 工作流审批操作
 * @author 魏荣杰
 *
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/workflowApproval")
public class WorkflowApprovalOperatorController {

    @Resource
    private WorkflowApprovalOperatorService workflowApprovalOperatorService;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    /**
     * Description: 同意
     * @param workflowCommitDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:48
     * @since
     */
    @RequestMapping(value = "/commit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String commit(@RequestBody @Valid WorkflowCommitDTO workflowCommitDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowCommitDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowCommitDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.commit(workflowCommitDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 拒绝
     * @param workflowRefuseDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:48
     * @since
     */
    @RequestMapping(value = "/refuse", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String refuse(@RequestBody @Valid WorkflowRefuseDTO workflowRefuseDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowRefuseDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowRefuseDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.refuse(workflowRefuseDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 暂存
     * @param workflowStorageDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:49
     * @since
     */
    @RequestMapping(value = "/storage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String storage(@RequestBody @Valid WorkflowStorageDTO workflowStorageDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowStorageDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowStorageDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.storage(workflowStorageDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 转交/管理员转交
     * @param workflowTransferDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:49
     * @since
     */
    @RequestMapping(value = "/transfer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String transfer(@RequestBody @Valid WorkflowTransferDTO workflowTransferDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowTransferDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowTransferDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.transfer(workflowTransferDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 撤回
     * @param workflowRevokeDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:49
     * @since
     */
    @RequestMapping(value = "/revoke", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String revoke(@RequestBody @Valid WorkflowRevokeDTO workflowRevokeDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowRevokeDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowRevokeDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.revoke(workflowRevokeDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 回退
     * @param workflowBackDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:49
     * @since
     */
    @RequestMapping(value = "/back", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String back(@RequestBody @Valid WorkflowBackDTO workflowBackDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowBackDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowBackDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.back(workflowBackDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 重新提交
     * @param workflowCommitAgainDTO
     * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/6/1 10:49
     * @since
     */
    @RequestMapping(value = "/commitAgain", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String commitAgain(@RequestBody @Valid WorkflowCommitAgainDTO workflowCommitAgainDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowCommitAgainDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowCommitAgainDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.commitAgain(workflowCommitAgainDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * Description: 加签
     * @param workflowAddSignatureDTO
	 * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2022/7/12 16:22
     * @since
     */
    @RequestMapping(value = "/addSignature", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addSignature(@RequestBody @Valid WorkflowAddSignatureDTO workflowAddSignatureDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowAddSignatureDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowAddSignatureDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                BaseVO baseVO = workflowApprovalOperatorService.addSignature(workflowAddSignatureDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 加签弹窗
     * @param workflowSignatureItemDTO
	 * @param br
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2022/7/13 19:30
     * @since
     */
    @RequestMapping(value = "/signatureItem", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String signatureItem(@RequestBody @Valid WorkflowSignatureItemDTO workflowSignatureItemDTO, BindingResult br) {
        XbbResponse<WorkflowAddSignatureVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {

            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(workflowSignatureItemDTO.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(workflowSignatureItemDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }

            try {
                WorkflowAddSignatureVO workflowAddSignatureVO = workflowApprovalOperatorService.signatureItem(workflowSignatureItemDTO);
                response = new XbbResponse<>(workflowAddSignatureVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
}
